package vip.zcn.mrn.service.impl;

import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import vip.zcn.mrn.service.CouponService;

/**
 * 优惠券服务实现类
 * 提供优惠券抢购功能，基于Redis实现库存控制和用户领取记录
 * @author 张灿能
 * @create: 2025-08-04 15:15
 */
@Service
@RequiredArgsConstructor
public class CouponServiceImpl implements CouponService {
    // Redis操作模板，用于操作Redis中的数据
    private final RedisTemplate<String, Object> redisTemplate;
    // 优惠券库存键名
    private static final String STOCK_KEY = "coupon_stock";
    // 用户领取记录键名前缀
    private static final String USER_KEY_PREFIX = "coupon_user_";

    /**
     * 初始化方法，在对象创建完成后执行
     * 检查Redis中是否存在库存键，如果不存在则初始化库存为100
     */
    @PostConstruct
    public void initStock() {
        // 判断库存键是否存在
        if (Boolean.FALSE.equals(redisTemplate.hasKey(STOCK_KEY))) {
            // 如果不存在，则设置初始库存为100
            redisTemplate.opsForValue().set(STOCK_KEY, "100");
        }
    }

    /**
     * 抢购优惠券方法
     * @param userId 用户ID
     * @return 领取结果信息
     */
    @Override
    public String grabCoupon(String userId) {
        // 构造用户领取记录键名
        String userKey = USER_KEY_PREFIX + userId;
        // 检查用户是否已经领取过优惠券
        if (Boolean.TRUE.equals(redisTemplate.hasKey(userKey))) {
            return "您已领取过优惠券";
        }

        // 获取当前库存数量
        Long stock = Long.valueOf((String) redisTemplate.opsForValue().get(STOCK_KEY));
        // 判断库存是否已经为0或负数
        if (stock <= 0) {
            return "优惠券已抢完";
        }

        // 减少库存并获取新的库存数量
        Long newStock = redisTemplate.opsForValue().decrement(STOCK_KEY);
        // 判断扣减后库存是否仍然大于等于0
        if (newStock >= 0) {
            // 记录用户已领取优惠券
            redisTemplate.opsForValue().set(userKey, "1");
            return "领取成功，剩余库存:" + newStock;
        } else {
            // 库存不足，返回抢购失败信息
            return "优惠券已抢完";
        }
    }
}
